/**
 * Created by ZhangDawei on 2015/3/18.
 */

(function (win, $) {
    var Gtable;
    //常用dom字符
    var doms = {//可以自己配置适合自己的结构名称
        tablewrap:"gy-table-wrap",//表格的wrap
        table: "gy-table",//表格的名字
        theader: "gy-table-header",//表格头部
        theaderwrap: "gy-table-header-wrap",//表格头部
        bodywrap:"gy-table-body-wrap",//表格的主体的wrap
        tbody: "gy-table-body",//表格的主体
        colname:"gy-col-name",//表格的列的名字
        col:"tb-col",//表格的列的名字
        tbcell :"tb-cell",//表格的单元格
        cellinner:"tb-cell-inner",//单元格内容
        rownum :"tb-row-num",//行号单元格的class
        selected:"selected"
    };

    //入口
    win.GridTable = function (opts) {
        return new Gtable(opts);
    };

    //主框架
    Gtable = function (opts) {
        var _this = this,
            proxy = null,
            limitSize,
            limitName,
            pageNum = 0,
            pageName = 0,
            setProxy = null,
            Gt = GridTable;
        _this.opts = opts;
        _this.configs = {//参数初始化设置
            proxy: {
                param: {}
            }
        };
        if (Gt.isArray(opts.data)) {//初始化静态数据
            _this.opts.data = opts.data;
        }

        if (Gt.isObject(_this.opts.proxy)) {//初始化远程请求参数
            proxy = _this.opts.proxy;
            setProxy = _this.configs.proxy;
            if (Gt.isObject(proxy.pageParam)) {//初始化prox的分页参数
                limitSize = proxy.pageSize ? proxy.pageSize : 10;
                limitName = proxy.pageParam.pageSize || '';
                pageName = proxy.pageParam.page || '';
                pageNum = proxy.page ? proxy.page : 1;
                limitName ? (setProxy.param[limitName] = limitSize) : (setProxy.param.limit = limitSize);
                pageName ? (setProxy.param[pageName] = pageNum) : (setProxy.param.page = pageNum);
            }
            if (Gt.isObject(proxy.param)) {//初始化其他请求参数
                setProxy.param = $.extend(proxy.param, setProxy.param);
            }
        }
        _this.init();
    };

    Gtable.prototype = {
        constructor: Gtable,
        init: function () {
            this.creating();
        },
        creating: function () {
            this.tb = this.gridView = this.buildHtml();
            this.computeTbSize();
            this.getData();
        },
        buildHtml: function () {
            var _this = this,
                Gt = GridTable,
                tb,
                opts = _this.opts,
                columns,
                colLth,
                colW,
                condition = Gt.isArray(opts.columns),
                tTable = "<div "+( opts.id ? "id='"+ opts.id+"'" :"")+" class='" + doms.tablewrap+' '+(opts.elementCls||'') + "' style='" + ( opts.width ? 'width:'+ opts.width+'px;' :'') + ' ' + ( opts.height ? 'height:'+ opts.height + 'px;' :'') + "'><div class='" + doms.table + "'><div class='" + doms.theaderwrap + "'><div class='" + doms.theader + "'>",
                colgroup = "",
                tBody = "<div class='" + doms.bodywrap + "'><table class='" + doms.tbody + "' border='0' cellpadding='0' cellspacing='0'>";

                if (condition) {
                    columns = opts.columns;
                    colLth = columns.length;
                    if(Gt.isObject(opts.rowNum)) {
                        tTable += "<div class='" + doms.col + "' "+ (opts.rowNum.width ? "style='width:"+opts.rowNum.width+"px;'":'') +"><div class='" + doms.colname + "'><div class='" + doms.cellinner + "' ></div></div></div>";
                        colgroup += "<colgroup class='"+ doms.rownum +"'><col></colgroup>";
                    }
                    for (var k = 0; k < colLth; k++) {
                        colW = (columns[k]['width'] ? "style='width:"+columns[k]['width']+"px;'":'');

                        tTable += "<div  class='" + doms.col + "' "+ colW +"><div class='" + doms.colname + "'><div class='" + doms.cellinner + ' ' +columns[k]['elementCls']+ "' >" + columns[k]['text'] + "</div></div></div>";
                        colgroup += "<colgroup "+ colW +"><col></colgroup>";
                    }
                    tTable += "</div></div>" + tBody + colgroup + "<tbody></tbody></table></div></div></div>";//组合表格头部和colgroup+表格内容;
                    tb = $(tTable).appendTo($(opts.renderTo && typeof (opts.renderTo) ? opts.renderTo : "body"));
                    //根据数据来渲染表格行数据
                }
            return tb;
        },

    //style='"+columns[k]['width']+"'

        buildRow: function (data) {
            var _this = this,
                dataLth,
                td,
                opts = _this.opts,
                isObj = GridTable.isObject(opts.rowNum),
                columns = opts.columns,
                colLth = opts.columns.length,
                trs = '';

            if (data && data instanceof Array) {
                dataLth = data.length;
                if (dataLth) {
                    for (var i = 0; i < dataLth; i++) {//表格行渲染
                        if(isObj){
                            trs += "<tr><td><div class='" + doms.cellinner+' '+doms.rownum + "'>" +(i+1)+ "</div></td>";
                        }else{
                            trs +="<tr>"
                        }
                        for (var j = 0; j < colLth; j++) {//表格列渲染
                            trs += "<td><div class='" + doms.cellinner + ' ' +columns[j]['elementCls']+ "'>" + data[i][columns[j]['dataIndex']] + "</div></td>";
                        }
                        trs += "</tr>";
                    }
                }
            }
            return trs;
        },

        computeTbSize: function () {
            var _this = this,
                opts = _this.opts,
                tb = _this.tb,
                totalW = 0,
                tBodyH,
                colW,
                tHeaderWrap,
                tHeader,
                tBody,
                col = tb.find("." + doms.col),
                colIdx;

            tb.find("colgroup").each(function (idx) {//给表格主体列的宽度复制
                colIdx = col.eq(idx);
                colW = colIdx.width();
                colIdx.width(colW);
                $(this).find("col").width(colW);
                totalW += colW;//所有列的宽度的总和
            });

            tBody = tb.find("." + doms.bodywrap);
            tHeaderWrap = tb.find("." + doms.theaderwrap);
            tHeader = tb.find("." + doms.theader);
            tHeader.width(totalW);
            if (opts.height) {
                tBodyH = opts.height;
                if (opts.width) {
                    tb.find(doms.table).outerWidth(opts.width);
                }
                tBody.outerHeight(tBodyH - tHeader.outerHeight());
            }

            tHeaderWrap.outerHeight(tHeader.outerHeight());
            tb.find("table").outerWidth(totalW + 1);//表格的主体宽度
            tBody.scroll(function () {
                var _$this = $(this);
                tHeader.css({left: -_$this.scrollLeft()});
            })
        },

        getData: function () {//获取行列数据
            var _this = this,
                opts = _this.opts,
                readerData,
                configs = _this.configs,
                Gt = GridTable;

            if (Gt.isObject(opts.proxy)) {
                if(opts.proxy.url) {
                    $.ajax({
                        type: opts.proxy.type || "POST",
                        url: opts.proxy.url,
                        data: configs.proxy.param,
                        dataType: opts.proxy.dataType || "json",
                        success: function (data, textStatus) {
                            if(Gt.isObject(opts.proxy.reader) && opts.proxy.reader.root) {
                                readerData = data.rows;
                            }else{
                                readerData = data;
                            }
                            _this.dataConvert(readerData);
                            _this.load(_this.store.view);
                            opts.loaded(_this);
                        },
                        error: function (data, textStatus) {
                            console.log(textStatus);
                        }
                    });
                }
            }

            if(Gt.isArray(opts.data)) {
                _this.dataConvert(opts.data);
                _this.load(_this.store.view);
            }

        },

        dataConvert: function(data){
            var _this = this,
                opts = _this.opts,
                dataLth = data.length,
                columns = opts.columns,
                colLth = columns.length,
                cellValue,
                Gt = GridTable;

            _this.store = {};
            _this.store.modifyRaw = [];

            _this.store.data =  Gt.clone(data);
            _this.store.view = Gt.clone(data);
            _this.store.raw = Gt.clone(data);

            for (var i = 0; i < dataLth; i++) {
                for (var j = 0; j < colLth; j++) {
                    if (('convert' in columns[j]) && typeof columns[j]['convert'] == 'function') {
                        cellValue = columns[j]['convert'](data[i][columns[j]['dataIndex']]);
                        if (cellValue) {
                            this.store.view[i][columns[j]['dataIndex']] = cellValue;
                        }
                    }
                }
            }
        },

        load: function (data) {
            var _this = this,
                tb = _this.tb,
                opts = _this.opts,
                selected = opts.selectedName || doms.selected;
                tb.find('tBody').html(_this.buildRow(data));

            if(!opts.seleted || opts.seleted == 'single') {
                _this.tb.find('tr').on('click',function(){
                    _this.store.selected ={};
                    var that = $(this),
                        idx = that.index();
                    if(that.hasClass(selected)) {
                        that.removeClass(selected);
                        delete _this.store.selected[idx];
                    }else{
                        that.addClass(selected).siblings().removeClass(selected);
                        _this.store.selected = _this.store.data[idx];
                        _this.store.selected[idx] = (_this.store.data[idx]);
                    }
                    console.log(_this.store.selected)
                })
            }else if(opts.seleted == 'multiple'){
                _this.store.selected ={};
                _this.tb.find('tr').on('click',function(){
                    var that = $(this),
                        idx = that.index();
                    if(that.hasClass(doms.seleted)) {
                        that.removeClass(selected);
                         delete _this.store.selected[idx];
                    }else{
                        that.addClass(selected);
                        _this.store.selected[idx] = (_this.store.data[idx]);
                    }
                })
            }

        }
    };

    //公共属性(方法)
    GridTable.isArray = function (arr) {//判断是否为数组，且数组不为空
        return arr && (typeof arr == 'object') && arr.length;
    };
    GridTable.isObject = function (obj) {//判断是否为object
        return obj && typeof obj == 'object' && !obj.length;
    };

    GridTable.clone = function(obj) {//对象的拷贝
        var newObj = {};
        if(typeof (obj) != 'object' || obj == null) {
            return obj;
        }
        if(obj.length) {
            newObj = [];
            for(var j = 0 ; j < obj.length ; j++ ) {
                newObj.push(GridTable.clone(obj[j]));
            }
        }else {
            for (var i in obj){
                newObj[i] = GridTable.clone(obj[i]);
            }
        }
        return newObj;
    };


})(window, jQuery);
